/*
 * Copyright (C) 2013. Young,Fey <fey.young@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.youngfey.database

import groovy.sql.Sql
import groovy.util.logging.*

import javax.sql.DataSource
import java.sql.Connection

/**
 * JDBC驱动的数据库工具类，用于产生简单的SQL连接和SQL对象
 * @author Young,Fey <fey.young@gmail.com>
 * @version 0.1.d
 * Created at 2013-04-24 11:37
 */

@Log
abstract class Database {
    /**
     * 连接失败时的重试次数限制
     */
    static final RETRY_LIMIT = 10
    /**
     * 每次重试等待时间中增加的毫秒数
     */
    static final STEP = 5000L

    /**
     * (当发生异常时)重置数据库连接并尝试释放连接资源
     */
    void reset() {
        try {
            sql = null
            connection.close()
        } catch (e) {
            log.warning "Failed to close connection: $e"
        } finally {
            connection = null
            wait = 0
        }
    }

    Connection getConnection() {
        while(!connection && wait < STEP * RETRY_LIMIT) {
            sleep wait
            try {
                connection = dataSource.connection
            } catch (e) {
                log.warning "Failed to connect: $e"
                wait += STEP
            }
        }
        if(connection) {
            wait = 0L
        } else {
            throw new NoConnectionException()
        }
        connection
    }

    Sql getSql() {
        if (sql == null) {
            sql = new Sql(dataSource)
        }
        sql
    }

    protected DataSource dataSource
    protected Connection connection
    protected Sql sql

    private long wait = 0L
}
